#include "TDiccionario.h"
#include <string.h>
#include "common.h"
#include "ListaSimple.h"
#include <malloc.h>
#include <memory.h>

void LiberarItemDiccionario(NodoDiccionario *item)
{
    if(item->clave)
        free(item->clave);
    if(item->valor)
        free(item->valor);
}

void CopiarItemDiccionario(NodoDiccionario *destino,NodoDiccionario *origen)
{
    destino->clave = (char*)malloc(strlen(origen->clave)+1);

    destino->valor = (char*)malloc(strlen(origen->valor)+1);

    if(!destino->clave || !destino->valor )
    {
        LiberarItemDiccionario(destino);

    }else
    {
        strcpy(destino->clave,origen->clave);
        strcpy(destino->valor,origen->valor);
    }
}

int clvcmp(void* nodo1, void* nodo2)
{
    NodoDiccionario* ndic1 = (NodoDiccionario*)nodo1;
    NodoDiccionario* ndic2 = (NodoDiccionario*)nodo2;

    return strcmp(ndic1->clave, ndic2->clave);
}

int TDiccionaro_Crear(TDiccionario* td)
{
    lso_Crear(&td->lso, sizeof(NodoDiccionario),(fCopyItemLista)CopiarItemDiccionario,(fDestroyItemLista)LiberarItemDiccionario,clvcmp);

    return 0;
}

int Tdiccionario_Destruir(TDiccionario* td)
{
    lso_Vaciar(&td->lso);

    return 0;
}

int TDiccionario_colocar(TDiccionario* td, char* clave, char* valor)
{
    NodoDiccionario *itemDiccionario;
    Boolean encontrado = False;

    itemDiccionario = (NodoDiccionario*)malloc (sizeof(NodoDiccionario));

    if (!lso_Vacia(&td->lso))
    {
        lso_ElemCorriente(&td->lso,(void*) itemDiccionario);

        if(strcmp(clave,itemDiccionario->clave) < 0)
            lso_MoverCorriente(&td->lso, LS_PRIMERO);

        LiberarItemDiccionario(itemDiccionario);

        do
        {
          lso_ElemCorriente(&td->lso, (void*) itemDiccionario);

          if (strcmp( itemDiccionario->clave, clave )==0)
          {
              encontrado = True;

          }
          if (!encontrado)
            LiberarItemDiccionario(itemDiccionario);

        }while(!encontrado && lso_MoverCorriente(&td->lso, LS_SIGUIENTE));
    }

    if (encontrado)
    {
        free(itemDiccionario->valor);
        itemDiccionario->valor = malloc(strlen(valor)+1);
        strcpy(itemDiccionario->valor,valor);

        lso_ModifCorriente(&td->lso, itemDiccionario);
    }
    else
    {
        itemDiccionario->clave = malloc(strlen(clave)+1);
        itemDiccionario->valor = malloc(strlen(valor)+1);

        strcpy(itemDiccionario->clave,clave);
        strcpy(itemDiccionario->valor,valor);

        lso_Insertar(&td->lso, itemDiccionario);
    }

    LiberarItemDiccionario(itemDiccionario);

    free(itemDiccionario);

    return 0;
}

int TDiccionario_obtener(TDiccionario* td, char* clave,char* buffer)
{
    NodoDiccionario *itemDiccionario;
    Boolean encontrado = False;
    itemDiccionario = (NodoDiccionario*)malloc (sizeof(NodoDiccionario));

    /*Seteo en vacio buffer, asi sino encuentra el dato devuelve un string vacio*/
    buffer[0] = 0;


    if (!lso_Vacia(&td->lso))
    {
         lso_ElemCorriente(&td->lso,(void*) itemDiccionario);

         if(strcmp(clave,itemDiccionario->clave) < 0)
            lso_MoverCorriente(&td->lso, LS_PRIMERO);

         LiberarItemDiccionario(itemDiccionario);

        do
        {
          lso_ElemCorriente(&td->lso, (void*) itemDiccionario);


          if (strcmp( itemDiccionario->clave, clave )==0)
          {
              strcpy(buffer,itemDiccionario->valor);
              encontrado = True;
          }

         LiberarItemDiccionario(itemDiccionario);

        }while(!encontrado && lso_MoverCorriente(&td->lso, LS_SIGUIENTE));

    }

    free(itemDiccionario);
    return 0;
}

int TDiccionario_sizeDato(TDiccionario* td, char* clave)
{
    int tamanio = 0;

    NodoDiccionario *itemDiccionario;
    Boolean encontrado = False;
    itemDiccionario = (NodoDiccionario*)malloc (sizeof(NodoDiccionario));


    if (!lso_Vacia(&td->lso))
    {
         lso_ElemCorriente(&td->lso,(void*) itemDiccionario);

         if(strcmp(clave,itemDiccionario->clave) < 0)
            lso_MoverCorriente(&td->lso, LS_PRIMERO);

         LiberarItemDiccionario(itemDiccionario);

        do
        {
          lso_ElemCorriente(&td->lso, (void*) itemDiccionario);

          if (strcmp( itemDiccionario->clave, clave )==0)
          {
              tamanio = strlen(itemDiccionario->valor);
              encontrado = True;
          }

         LiberarItemDiccionario(itemDiccionario);

        }while(!encontrado && lso_MoverCorriente(&td->lso, LS_SIGUIENTE));

    }

    free(itemDiccionario);

    return tamanio;
}


int TDiccionario_Cant_Elementos(TDiccionario *td)
{
    int cantidadElementos = 0;

    if (!lso_Vacia(&td->lso))
    {
        lso_MoverCorriente(&td->lso, LS_PRIMERO);

        do
        {
          cantidadElementos++;
        }while(lso_MoverCorriente(&td->lso, LS_SIGUIENTE));

    }

    return cantidadElementos;
}


